// filefunc.cpp -- function with ostream & parameter
#include <iostream> // 引入输入输出流库
#include <fstream>  // 引入文件流库
#include <cstdlib>  // 引入 C 标准库，提供 exit 函数
using namespace std; // 使用标准命名空间，方便调用标准库函数

// 函数声明：file_it 函数用于输出焦距数据到指定的输出流
void file_it(ostream &os, double fo, const double fe[], int n);

// 定义常量 LIMIT，表示目镜的数量
const int LIMIT = 5;

int main() {
    ofstream fout; // 创建一个文件输出流对象
    const char *fn = "ep-data.txt"; // 定义输出文件名
    fout.open(fn); // 打开文件写入数据
    // 检查文件是否成功打开
    if (!fout.is_open()) {
        cout << "Can't open " << fn << ". Bye.\n"; // 输出错误消息
        exit(EXIT_FAILURE); // 如果不能打开文件，退出程序
    }

    double objective; // 声明一个变量存储望远镜的焦距
    cout << "Enter the focal length of your "
            "telescope objective in mm: "; // 提示用户输入望远镜焦距
    cin >> objective; // 读取用户输入的焦距

    double eps[LIMIT]; // 创建数组存储目镜的焦距
    cout << "Enter the focal lengths, in mm, of " << LIMIT
            << " eyepieces:\n"; // 提示用户输入目镜焦距
    for (int i = 0; i < LIMIT; i++) {
        cout << "Eyepiece #" << i + 1 << ": "; // 提示输入每个目镜的焦距
        cin >> eps[i]; // 读取每个目镜的焦距
    }

    // 调用 file_it 函数，将数据写入文件和控制台
    file_it(fout, objective, eps, LIMIT);
    file_it(cout, objective, eps, LIMIT);

    cout << "Done\n"; // 输出程序完成的信息
    // cin.get(); // 取消注释可用于等待用户输入
    // cin.get(); // 取消注释可用于等待用户输入
    return 0; // 程序正常结束
}

// 函数定义：file_it，用于输出焦距信息到指定的输出流
void file_it(ostream &os, double fo, const double fe[], int n) {
    // 保存初始的格式状态
    ios_base::fmtflags initial; // 用于保存当前的格式标志
    initial = os.setf(ios_base::fixed, ios_base::floatfield); // 设置为固定格式
    std::streamsize sz = os.precision(0); // 保存当前精度

    // 输出望远镜的焦距
    os << "Focal length of objective: " << fo << " mm\n";

    // 设置格式并输出标题
    os.precision(1); // 设置精度为 1
    os.width(12); // 设置字段宽度为 12
    os << "f.l. eyepiece"; // 输出目镜焦距标题
    os.width(15); // 设置字段宽度为 15
    os << "magnification" << endl; // 输出放大倍数标题

    // 计算并输出每个目镜的焦距和对应的放大倍数
    for (int i = 0; i < n; i++) {
        os.width(12); // 设置字段宽度为 12
        os << fe[i]; // 输出目镜的焦距
        os.width(15); // 设置字段宽度为 15
        os << int(fo / fe[i] + 0.5) << endl; // 计算并输出放大倍数，四舍五入
    }

    // 恢复初始的格式状态
    os.setf(initial, ios_base::floatfield); // 恢复格式标志
    os.precision(sz); // 恢复原来的精度
}
